package com.lyc.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyc.common.model.entity.UserInterfaceInfo;
import com.lyc.project.common.ErrorCode;
import com.lyc.project.exception.BusinessException;
import com.lyc.project.mapper.UserInterfaceInfoMapper;
import com.lyc.project.model.dto.userinterfaceinfo.UserInterfaceInfoFreeUpdateRequest;
import com.lyc.project.service.UserInterfaceInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
* @author lyc
* @description 针对表【user_interface_info(用户调用接口关系)】的数据库操作Service实现
* @createDate 2023-06-15 16:41:49
*/
@Slf4j
@Service("userInterfaceInfo")
public class UserInterfaceInfoServiceImpl extends ServiceImpl<UserInterfaceInfoMapper, UserInterfaceInfo>
    implements UserInterfaceInfoService {

    @Resource
    private UserInterfaceInfoMapper userInterfaceInfoMapper;

    @Override
    public void validUserInterfaceInfo(UserInterfaceInfo userInterfaceInfo, boolean add) {
        if (userInterfaceInfo == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 创建时，所有参数必须非空
        if (add) {
            if (userInterfaceInfo.getInterfaceInfoId() <= 0 || userInterfaceInfo.getUserId() <= 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "接口或用户不存在");
            }
        }
        if (userInterfaceInfo.getLeftNum() < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "剩余次数不能小于0");
        }
    }

    @Override
    public boolean invokeCount(long interfaceInfoId, long userId) {
        //校验
        if (interfaceInfoId <= 0 || userId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        UpdateWrapper<UserInterfaceInfo> updateWrapper = new UpdateWrapper<>();
        boolean update;
        //加锁防止高并发
        synchronized (this){
            updateWrapper.eq("interfaceInfoId", interfaceInfoId);
            updateWrapper.eq("userId", userId);
            updateWrapper.setSql("leftNum = leftNum - 1, totalNum = totalNum + 1");
            update = this.update(updateWrapper);
        }
        return update;
    }

    /**
     * 获取免费接口调用
     * @param userInterfaceInfoFreeUpdateRequest
     * @return
     */
    @Override
    public boolean updateUserInterfaceInfo(UserInterfaceInfoFreeUpdateRequest userInterfaceInfoFreeUpdateRequest) {
        Long userId = userInterfaceInfoFreeUpdateRequest.getUserId();
        Long interfaceInfoId = userInterfaceInfoFreeUpdateRequest.getInterfaceInfoId();
        Long freeCount = userInterfaceInfoFreeUpdateRequest.getFreeCount();
        if( userId == null || interfaceInfoId== null || freeCount == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        LambdaQueryWrapper<UserInterfaceInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(UserInterfaceInfo::getUserId, userId).eq(UserInterfaceInfo::getInterfaceInfoId, interfaceInfoId);
        UserInterfaceInfo userInterfaceInfo = this.getOne(lqw);
        // 是否是第一次获取接口
        if (userInterfaceInfo == null) {
            // 如果是第一次，就直接给用户添加这个接口
            UserInterfaceInfo newUserInterfaceInfo = new UserInterfaceInfo();
            newUserInterfaceInfo.setUserId(userId);
            newUserInterfaceInfo.setInterfaceInfoId(interfaceInfoId);
            newUserInterfaceInfo.setLeftNum(Math.toIntExact(freeCount));
            return this.save(newUserInterfaceInfo);
        }else{
            // 如果不是第一次，就直接加次数
            LambdaUpdateWrapper<UserInterfaceInfo> upLqw = new LambdaUpdateWrapper<>();
            upLqw.eq(UserInterfaceInfo::getUserId, userId);
            upLqw.eq(UserInterfaceInfo::getInterfaceInfoId, interfaceInfoId);
            upLqw.setSql("leftNum = leftNum + " + freeCount);
            boolean update = this.update(upLqw);
            if(!update) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR);
            }
            log.info(userId + "获取免费接口 " + interfaceInfoId + "成功，调用次数增加" + freeCount);
            return true;
        }
        
    }

}




